<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>
<script>
    //【1】松弛绑定
    // 默认情况下，underscore 对象 _ 会覆盖全局对象上同名的 _ 属性。但是，underscore 也不过于蛮横，他会保存之前已经存在的 _ 属性, 因为像是 lodash这样的一些库也喜欢将自己的对象命名为 _

    var previousUnderscore = root._; //lodash库的下划线

    // 当用户已经在全局对象上绑定了 _ 对象时，可以通过 underscore 提供的noConflict 函数来重命名 underscore 对象，
    // 或者说是手动获得 underscore 对象，避免与之前的 _ 冲突：
    var underscore_sky = _.noConflict();


    // 看到 noConflict 的源码实现，我们发现，在其内部，将会恢复原来全局对象上的 _:
    _.noConflict = function() {
        // 回复原来的_指代的对象
        root._ = previousUnderscore;
        // 返回 underscore 对象
        return this;
    };

    // 【2】局部变量妙用

    // underscore 本身也依赖了不少 js 的原生方法，如下代码所示，underscore 会通过局部变量来保存一些他经常用到的方法或者属性，这样做的好处有如下两点：
    //（1）在后续使用到这些方法或者属性时，避免了冗长的代码书写。
    //（2）减少了对象成员的访问深度，( Array.prototype.push --> push ), 这样做能带来一定的性能提升，具体可以参看 《高性能 javascript》

    var ArrayProto = Array.prototype,
        ObjProto = Object.prototype;
    var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
    var push = ArrayProto.push,
        slice = ArrayProto.slice,
        toString = ObjProto.toString,
        hasOwnProperty = ObjProto.hasOwnProperty;
</script>

</html>